home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / p063b9s.zip / UNIT / MSGPACK.PAS < prev    next >
Pascal/Delphi Source File  |  1996-04-20  |  15KB  |  524 lines

  1. Unit MsgPack;
  2. {╔══════════════════════════════════════════════════════════════════════════╗}
  3. {║ Mail packer                                   Last changed: 20.04.96 SA  ║}
  4. {║                                                                          ║}
  5. {║                         (C) Copyright 1989-93 by                         ║}
  6. {║       Dan Wulff, Jens Sandalgaard, Steen Christensen & S¢ren Ager        ║}
  7. {║                                                                          ║}
  8. {║ This source may not be given to anybody, without the written permission  ║}
  9. {║ from The Portal Team.                                                    ║}
  10. {╚══════════════════════════════════════════════════════════════════════════╝}
  11. {$I POPDEFS.INC}
  12.  
  13. interface
  14.  
  15. USES Use32;
  16.  
  17. procedure PackMsg(renumber: boolean);
  18.  
  19.  
  20. Implementation
  21.  
  22. uses Util, fileutil, logfile, dos, globals,
  23.      OpDate, OpString, OproUtil, OpWindow, Opcrt, netfile, Oplarray, poptypes;
  24.  
  25. Procedure PackMsg(renumber : boolean);
  26. type
  27.  
  28.   LASTREADType = ARRAY[1..200] of Integer;
  29.  
  30.   listerecord = record
  31.     conf      : byte;
  32.     maildate  : s8;
  33.     deleted   : boolean;
  34.     filer     : byte;
  35.     DontTouch : Boolean;
  36.     fP        : Longint;
  37.     filler    : Byte;
  38.   end;
  39.  
  40.   renumrecord = record
  41.     board     : byte;
  42.     oldnum    : integer;
  43.     filler    : Byte;
  44.   end;
  45.  
  46.   var
  47.     outputfile,
  48.     inputfile       : file;
  49.     outputrec,
  50.     inputrec        : HudsonHdrrecord;
  51.     txtoutfile,
  52.     txtinfile       : File;
  53.     txtstring       : string;
  54.     i,c             : integer;
  55.     headers         : Oparray;
  56.     header          : listerecord;
  57.     Msgtab          : Oparray;
  58.     Msg             : Renumrecord;
  59.     AreaCount       : Word;
  60.     astcount        : SHORTINT;
  61.     Win             : WindowPtr;
  62.     Area            : TmsgArea;
  63.     AreaFile        : File;
  64.     etrec,torec,
  65.     x               : Listerecord;
  66.     idxfile         : file;
  67.     idxtofile       : file;
  68.     idxrec          : hudsonidxrecord;
  69.     idxtorec        : s35;
  70.     inforec         : hudsoninforecord;
  71.     infofile        : file;
  72.     BasePath        : PathStr;
  73.  
  74.   Procedure SkrivAst;
  75.   Var
  76.     Ch : Char;
  77.   Begin
  78.     inc(AstCount);
  79.     if Astcount>4 then astcount:=1;
  80.     Case AstCount of
  81.       1 : ch:='-';
  82.       2 : ch:='\';
  83.       3 : ch:='|';
  84.       4 : ch:='/';
  85.     end;
  86.     win^.WFasttext(ch,1,13);
  87.   end;
  88.  
  89.  
  90.   procedure Indles;
  91.   Begin
  92.     NetOpenFile(inputfile,basepath+'msghdr.bbs',SizeOf(inputrec),FALSE);
  93.     headers.init(filesize(inputfile)+1,1,sizeof(listerecord),'portal.lar',maxavail div 2,lDeleteFile,DefaultPriority);
  94.     while not eof(inputfile) do
  95.     begin
  96.       NetGetRec(inputfile,inputrec,filepos(inputfile),keep,wait);
  97.       if netioresult=0 then
  98.       Begin
  99.         inc(AreaCount);
  100.         skrivast;
  101.         header.conf:=inputrec.board;
  102.         header.maildate:=inputrec.postdate;
  103.         header.deleted:=(inputrec.msgattr and 1) <> 0;
  104.         header.donttouch:=false;
  105.         Header.FP:=Filepos(inputfile)-1;
  106.         Headers.setA(header.FP+1,0,header);
  107.       end
  108.     end;
  109.   end;
  110.  
  111.   procedure writeheader(rec : integer);
  112.   Begin
  113.     headers.reta(rec,0,header);
  114.     seek(inputfile,rec);
  115.     NetGetRec(inputfile,inputrec,filepos(inputfile),keep,wait);
  116.     NetPutRec(Outputfile,inputrec,filesize(outputfile));
  117.   end;
  118.  
  119.  
  120.   procedure Sort(l, r: word);
  121.   var
  122.     i, j, y   : word;
  123.     x         : s10;
  124.     gem       : listerecord;
  125.  
  126.     function makekey(source : listerecord):s10;
  127.     var
  128.       tmp : s10;
  129.     Begin
  130.       tmp:=longintform('###',source.conf);
  131.       makekey:=tmp + longintform('#####',source.fp)
  132.     end;
  133.  
  134.   begin
  135.     skrivast;
  136.     i := l;
  137.     j := r;
  138.     Headers.reta(((l+r) DIV 2),0,gem);
  139.     x:=makekey(gem);
  140.     repeat
  141.       headers.reta(i,0,gem);
  142.       While makekey(gem) < x do
  143.       begin
  144.         if Headers.lasterror<>0 then break;
  145.         inc(i);
  146.         headers.reta(i,0,gem);
  147.       end;
  148.       Headers.reta(j,0,gem);
  149.       while x < makekey(gem) do
  150.       Begin
  151.         if Headers.lasterror<>0 then break;
  152.         dec(j);
  153.         Headers.reta(j,0,gem);
  154.       end;
  155.       if i <= j then
  156.       begin
  157.         headers.reta(i,0,etrec);
  158.         Headers.reta(j,0,torec);
  159.         Headers.Seta(j,0,etrec);
  160.         headers.Seta(i,0,torec);
  161.         inc(i);
  162.         dec(j);
  163.       end;
  164.     until i > j;
  165.     if l < j then Sort(l, j);
  166.     if i < r then Sort(i, r);
  167.   end;
  168.  
  169.  
  170.   Procedure Behandel;
  171.   var
  172.     Ok   : Boolean;
  173.     counter,
  174.     oldnext,
  175.     Next : word;
  176.     etrec,
  177.     torec,
  178.     gem  : Listerecord;
  179.  
  180.     Procedure FindBreak;
  181.     var
  182.       Old : Listerecord;
  183.       x,
  184.       i   : word;
  185.     Begin
  186.       x:=next;
  187.       Headers.RetA(x,0,old);
  188.       For i:=x to Areacount do
  189.       Begin
  190.         headers.reta(i,0,gem);
  191.         if gem.conf<>Old.conf then
  192.         begin
  193.           next:=i;
  194.           Break;
  195.         end;
  196.         if i=AreaCount then ok:=True;
  197.       end;
  198.     end;
  199.  
  200.     Function FindConf(conference :byte):boolean;
  201.     var
  202.       areas ,
  203.       test  : integer;
  204.       board : Byte;
  205.  
  206.     Begin
  207.       Findconf:=false;
  208.       areas:=0;
  209.       while not eof(AreaFile) do
  210.       begin
  211.         NetGetRec(AreaFile,Area,areas,nokeep,wait);
  212.         Val(area.directory,Board,test);
  213.         if conference=board then
  214.         Begin
  215.           findconf:=true;
  216.           break;
  217.         end;
  218.         inc(areas);
  219.       end;
  220.     end;
  221.  
  222.   Begin
  223.     ok:=false;
  224.     next:=1;
  225.     NetOpenFile(areafile,startpath+PoPMsgAreaFileName,SizeOf(TMsgArea),FALSE);
  226.     repeat
  227.       oldnext:=next;
  228.       FindBreak;
  229.       Headers.retA(oldnext,0,gem);
  230.       if findconf(gem.conf) then
  231.       begin
  232.         if area.msgkeep<> 0 then
  233.         Begin
  234.           if oldnext+area.msgkeep < next-1 then
  235.           begin
  236.             for counter:=oldnext to (oldnext+Area.msgkeep)-1 do
  237.             Begin
  238.               skrivast;
  239.               headers.reta(counter,0,gem);
  240.               gem.DontTouch:=True;
  241.               Headers.SetA(Counter,0,gem);
  242.             end;
  243.           end
  244.           else
  245.           begin
  246.             for counter:=oldnext to next-1 do
  247.             Begin
  248.               skrivast;
  249.               headers.reta(counter,0,gem);
  250.               gem.DontTouch:=True;
  251.               Headers.SetA(Counter,0,gem);
  252.             end;
  253.           end;
  254.         End;
  255.         if area.datecount<> 0 then
  256.         begin
  257.           for counter:=oldnext to next-1 do
  258.           begin
  259.             headers.reta(counter,0,gem);
  260.             if not gem.donttouch then
  261.             begin
  262.               if datestringTodate('MM-DD-YY',gem.maildate) < (today-area.datecount) then
  263.               Begin
  264.                 skrivast;
  265.                 gem.deleted:=true;
  266.                 headers.SetA(counter,0,gem)
  267.               end;
  268.             end;
  269.           end;
  270.         end;
  271.         if area.msgcount<> 0 then
  272.         begin
  273.           for counter:=next-1 downto oldnext do
  274.           begin
  275.             headers.reta(counter,0,gem);
  276.             if (not gem.donttouch) and (not gem.deleted) then
  277.             begin
  278.               skrivast;
  279.               if area.msgcount<=0 then
  280.               Begin
  281.                 gem.deleted:=true;
  282.                 headers.seta(counter,0,gem)
  283.               end
  284.               else
  285.                 dec(area.msgcount);
  286.             end;
  287.           end;
  288.         end;
  289.       end;
  290.     until Ok;
  291.     if Filerec(Areafile).mode<>FmClosed then NetCloseFile(areafile);
  292.   end;
  293.  
  294.  
  295.   Procedure UpdateLastRead;
  296.  
  297.     Procedure QbbsStyle;
  298.     Var
  299.       Lastreadfile : file;
  300.       lastreadrec  : LastReadType;
  301.       boardcount   : integer;
  302.  
  303.  
  304.       Function ReturnLastRead(board : byte; num : integer):integer;
  305.       var
  306.         MsgCounter : integer;
  307.         gem        : renumrecord;
  308.       Begin
  309.         Skrivast;
  310.         returnLastread:=0;
  311.         for msgcounter:=1 to Areacount do
  312.         begin
  313.           msgtab.reta(msgcounter,0,gem);
  314.           if (gem.oldnum=num) and (gem.board=board) then
  315.           begin
  316.             returnLastRead:=MsgCounter;
  317.             Break;
  318.           end;
  319.         end;
  320.       end;
  321.  
  322.     Begin
  323.       if cfg.BBs.userfile<>'' then
  324.       Begin
  325.         NetOpenFile(lastreadfile,JustPathName(cfg.bbs.userfile)+'\lastread.bbs',400,false);
  326.         if netioresult=0 then
  327.         Begin
  328.           While not eof(lastreadfile) do
  329.           begin
  330.             netread(lastreadfile,LastReadRec,keep,wait);
  331.  
  332.             for boardcount:=1 to 200 do
  333.               lastReadRec[boardcount]:=ReturnLastRead(Boardcount,LastReadRec[Boardcount]);
  334.             netputrec(lastreadfile,lastreadrec,filepos(lastreadfile)-1);
  335.           end;
  336.           netclosefile(lastreadfile);
  337.         end;
  338.       end;
  339.     end;
  340.  
  341.   Begin
  342.     Win^.Wfasttext('Upd. Lastr. ',1,2);
  343.     case cfg.bbs.bbstype of
  344.      1,6 : QbbsStyle;
  345.     end;
  346.   end;
  347.  
  348.  
  349.   Procedure WriteFile;
  350.   CONST MsgTxtMax = 5;
  351.   TYPE
  352.     TXTBufType = Array[1..msgtxtmax] of string;
  353.  
  354.   var
  355.     i, newnum,
  356.     oldstart,
  357.     counts       : word;
  358.     ReadCount,
  359.     LineCount    : Byte;
  360.     txtbuf       : ^txtbuftype;
  361.  
  362.   begin
  363.     PopGetMem(pointer(txtbuf),sizeof(TxtBufType));
  364.     if renumber then
  365.       msgtab.init(areacount,1,sizeof(Renumrecord),'popmsg.lar',maxavail div 2,lDeleteFile,DefaultPriority);
  366.     newnum:=0;
  367.     Deletefile(basepath+'msghdr.$$$');
  368.     Deletefile(basepath+'msgtxt.$$$');
  369.     NetOpenFile(Outputfile,basepath+'msghdr.$$$',SizeOf(inputrec),true);
  370.     NetOpenFile(txtinfile,basepath+'msgtxt.bbs',SizeOf(txtstring),FALSE);
  371.     NetOpenFile(txtOutfile,basepath+'msgtxt.$$$',SizeOf(txtstring),true);
  372.     if netioresult=0 then
  373.     begin
  374.       for counts:=1 to areacount do
  375.       begin
  376.         headers.reta(counts,0,x);
  377.         if not x.deleted then
  378.         Begin
  379.           Skrivast;
  380.           NetGetRec(inputfile,inputrec,x.fp,nokeep,wait);
  381.           IF NetIoResult=0 THEN
  382.           begin
  383.             if (x.conf=inputrec.board) and (x.maildate=inputrec.postdate) then
  384.             begin
  385.               oldstart:=inputrec.startrec;
  386.               inputrec.startrec:=filesize(txtoutfile);
  387.               if renumber then
  388.               begin
  389.                 inc(newnum);
  390.                 msg.Board:=inputrec.board;
  391.                 msg.Oldnum:=inputrec.msgnum;
  392.                 msgtab.seta(newnum,0,msg);
  393.                 inputrec.msgnum:=newnum;
  394.               end;
  395.               NetPutRec(Outputfile,inputrec,filesize(outputfile));
  396.               IF NetIoResult=0 THEN
  397. {                for I:=1 to inputrec.numrecs do
  398.                 begin
  399.                   NetGetRec(txtinfile,txtstring,oldStart+(i-1),nokeep,wait);
  400.                   if netioresult=0 then
  401.                     Netputrec(txtoutfile,txtstring,filesize(txtoutfile));
  402.                 end; }
  403.                 Begin
  404.                   readcount:=inputrec.numrecs;
  405.                   Seek(TxtInFile,oldstart);
  406.                   repeat
  407.                     if readcount > msgtxtmax then
  408.                       Linecount:=msgtxtmax
  409.                     else
  410.                       linecount:=readcount;
  411.                     Blockread(TxtInFile,txtbuf^,linecount);
  412.                     blockwrite(TxtOutFile,txtBuf^,linecount);
  413.                     dec(Readcount,linecount);
  414.                   until readcount=0;
  415.                 end;
  416.  
  417.             end;
  418.           end;
  419.         end;
  420.         if renumber then
  421.           areacount:=newnum;
  422.       end;
  423.       netclosefile(outputfile);
  424.       netclosefile(Txtinfile);
  425.       netclosefile(Txtoutfile);
  426.       if netioresult=0 then
  427.       Begin
  428.         Deletefile(basepath+'msghdr.BBS');
  429.         Deletefile(basepath+'msgtxt.BBS');
  430.         renameFile(basepath+'msghdr.$$$',basepath+'msghdr.bbs');
  431.         renameFile(basepath+'msgtxt.$$$',basepath+'msgtxt.bbs');
  432.       end;
  433.     end;
  434.     PopFreeMem(pointer(txtbuf),sizeof(TxtBufType));
  435.     if renumber then
  436.     begin
  437.       UpdateLastRead;
  438.       msgtab.done;
  439.     end;
  440.   end;
  441.  
  442.  
  443.   procedure reindex;
  444.   begin
  445.     Deletefile(basepath+'msgidx.bbs');
  446.     Deletefile(basepath+'msgtoidx.bbs');
  447.     NetOpenFile(Outputfile,basepath+'msghdr.bbs',SizeOf(inputrec),false);
  448.     NetOpenFile(idxfile,basepath+'msgidx.bbs',SizeOf(idxrec),true);
  449.     NetOpenFile(idxtofile,basepath+'msgtoidx.bbs',SizeOf(idxtorec),true);
  450.     NetOpenFile(infofile,basepath+'msginfo.bbs',SizeOf(inforec),true);
  451.     fillchar(inforec,sizeof(inforec),0);
  452.     inforec.lowmsg:=32767;
  453.     if netioresult=0 then
  454.     begin
  455.       while not eof(outputfile) do
  456.       begin
  457.         Skrivast;
  458.         netread(outputfile,inputrec,nokeep,wait);
  459.         idxrec.msgnum:=inputrec.msgnum;
  460.         idxrec.board:=inputrec.board;
  461.         netwrite(idxfile,idxrec);
  462.         if (inputrec.msgattr and qbdeleted)<>0 then
  463.           idxtorec:='* Deleted *'
  464.         else
  465.         begin
  466.           if (inputrec.msgattr and qbreceived)<>0 then
  467.             idxtorec:='* Received *'
  468.           else
  469.             idxtorec:=inputrec.whoto;
  470.  
  471.           if inputrec.msgnum < inforec.lowmsg then
  472.             inforec.lowmsg:=inputrec.msgnum
  473.           else
  474.             if inputrec.msgnum > inforec.highmsg then
  475.               inforec.highmsg:=inputrec.msgnum;
  476.           inc(inforec.totalactive);
  477.           inc(inforec.activemsgs[inputrec.board]);
  478.         end;
  479.         netwrite(idxtofile,idxtorec);
  480.       end;
  481.       netclosefile(outputfile);
  482.       netclosefile(idxfile);
  483.       netclosefile(idxtofile);
  484.       netwrite(infofile,inforec);
  485.       netclosefile(infofile);
  486.     end;
  487.   end;
  488.  
  489. Begin
  490.   areaCount:=0;
  491.   MyWin(win,10,10,24,13,2,'Msg.Pack',true);
  492.   NetOpenFile(areafile,startpath+PoPMsgAreaFileName,SizeOf(TMsgArea),FALSE);
  493.   NetRead(areafile,area,Nokeep,wait);
  494.   IF POS('\',Area.Directory)>0 THEN
  495.   BEGIN
  496.     i:=LENGTH(Area.Directory);
  497.     WHILE Area.Directory[i]<>'\' DO
  498.       DEC(i);
  499.     BasePath:=COPY(Area.Directory,1,i);
  500.   END ELSE
  501.     BasePath:=StartPath;
  502.  
  503.   NetcloseFile(areafile);
  504.   NetOpenFile(infofile,basepath+'msginfo.bbs',SizeOf(inforec),true);
  505.   netread(infofile,inforec,nokeep,wait);
  506.   netclosefile(infofile);
  507.   if (cfg.mailscanner.renumthresh>0) and (inforec.highmsg >= Cfg.MailScanner.RenumThresh) then
  508.     renumber:=True;
  509.   Win^.Wfasttext('Reading  ',1,2);
  510.   Indles;
  511.   Win^.Wfasttext('Sorting  ',1,2);
  512.   sort(1,areacount);
  513.   Win^.Wfasttext('Working  ',1,2);
  514.   Behandel;
  515.   Win^.Wfasttext('Packing  ',1,2);
  516.   WriteFile;
  517.   Headers.done;
  518.   Win^.Wfasttext('Indexing ',1,2);
  519.   reindex;
  520.   KillWindow(win);
  521. end;
  522.  
  523. end.
  524.